/****************************************************
          File Name:52-3-server.c
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Sun 21 Sep 2014 02:41:37 PM CST
*****************************************************/

/* this programm can only read on file and then shall type ctrl+c to end it */

#include"mq.h"
#include<signal.h>
#include<sys/wait.h>

static char *tmp_mq;

void dealing(int sig)
{
    if(sig==SIGCHLD)
        waitpid(-1,NULL,WNOHANG);
    else if(sig==SIGINT)
    {
        if(mq_unlink(tmp_mq)==-1)
            err("unlink in signal handler");
        exit(EXIT_SUCCESS);
    }
}
void run(char *name,char *path,long size)
{
    int fd,s;
    mqd_t mq;
    char *buf;
    printf("%s \n",name);
    buf=malloc(size);
    if(buf==NULL)
        err("malloc");
    fd=open(path,O_RDONLY);
    if(fd==-1)
        err("open file");
    mq=mq_open(name,O_RDWR);
    if(mq==(mqd_t)-1)
        err("mq_open");

    while(read(fd,buf,size)>0)
    {
        s=mq_send(mq,buf,size,0);
        if(s==-1)
            err("mq_send");
        memset(buf,0,size);    /* clean buf */
    }
    s=mq_send(mq,buf,0,0);          /* end sending data */
    if(s==-1)
        err("mq_send");

    close(fd);
}

int main(int argc,char *argv[])
{
    mqd_t mq;
    char *buf;
    pid_t pid;
    struct mq_attr attr;
    struct sigaction sa;

    if(argc<2 || strcmp(argv[1],"--help")==0)
    {
        printf("%s /mq\n",argv[0]);
        exit(EXIT_FAILURE);
    }

    mq=mq_open(argv[1],O_CREAT|O_RDWR,MODE,NULL);   /* use default attr */
    if(mq==(mqd_t)-1)
        err("creat mq");

    tmp_mq=argv[1];             /* for signal handler use */

    if(mq_getattr(mq,&attr)==-1)
        err("getattr");
    if(sigemptyset(&sa.sa_mask)==-1)
        err("sigemptyset");
    sa.sa_flags=SA_RESTART;
    sa.sa_handler=dealing;

    if(sigaction(SIGCHLD,&sa,NULL)==-1 || sigaction(SIGINT,&sa,NULL)==-1)
        err("sigaction");

    buf=malloc(attr.mq_msgsize);
    if(buf==NULL)
        err("malloc");
    
	if(mq_receive(mq,buf,attr.mq_msgsize,0)==-1)        /* block */
		err("receive path");
				
    pid=fork();
    if(pid==-1)
        err("fork");
    if(pid==0)
    {
        run(argv[1],buf,attr.mq_msgsize);
        exit(0);
    }
    for(;;)
        sleep(1);
    exit(EXIT_SUCCESS);                 /* never run */
}